namespace Plugins.Engine
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using Plugins.Engine.Internal;
    using Plugins.Interfaces;
    using Plugins.Library;

    [Serializable]
    public class PluginServiceManager : PluginServiceProvider<IPluginService>, IPluginServiceManagerInternal
    {
        private IPluginHostManager _manager;

        public PluginServiceManager(IPluginHostManager manager)
            : base(typeof(PluginServiceManager).GUID)
        {
            this._manager = manager;
        }

        public IPluginHostManager Host { get { return _manager; } }

        [SuppressMessage("Microsoft.Design", "CA1004")]
        public static int CountService<T>(IPluginServiceManager manager) where T : class, IPluginServiceProvider<T>
        {
            if (manager != null)
            {
                return manager.PluginService.GetTypeCount(typeof(IPluginService<T>));
            }
            return 0;
        }

        [SuppressMessage("Microsoft.Design", "CA1004")]
        [SuppressMessage("Microsoft.Design", "CA1006")]
        public static IEnumerable<IPluginService<T>> GetServices<T>(IPluginServiceManager manager)
        {
            if (manager != null)
            {
                IEnumerable<IPluginService> services = manager.PluginService.GetServices(typeof(IPluginService<T>));
                if (services != null)
                {
                    foreach (IPluginService service in services)
                    {
                        IPluginService<T> item = service as IPluginService<T>;
                        if (item != null)
                        {
                            yield return item;
                        }
                    }
                }
            }
        }

        [SuppressMessage("Microsoft.Design", "CA1004")]
        public static void RegisterService<T>(IPluginServiceManager control, IPluginService<T> service) where T : class, IPluginServiceProvider<T>
        {
            IPluginServiceManagerInternal manager = (IPluginServiceManagerInternal)control;
            if (manager != null)
            {
                manager.RegisterService<T>(service);
            }
        }

        [SuppressMessage("Microsoft.Design", "CA1004")]
        public static void UnregisterService<T>(IPluginServiceManager control, IPluginService<T> service) where T : class, IPluginServiceProvider<T>
        {
            IPluginServiceManagerInternal manager = (IPluginServiceManagerInternal)control;
            if (manager != null)
            {
                manager.UnregisterService<T>(service);
            }
        }

        [SuppressMessage("Microsoft.Design", "CA1004")]
        void IPluginServiceManagerInternal.RegisterService<T>(IPluginService<T> service)
        {
            if ((service != null) && PluginService.Register(typeof(IPluginService<T>), service))
            {
                PluginLog.WriteAsync(string.Format(CultureInfo.InvariantCulture, "register service={0}", PluginTypeHelper.GetTypeName(service.GetType())));
            }
        }

        [SuppressMessage("Microsoft.Design", "CA1004")]
        void IPluginServiceManagerInternal.UnregisterService<T>(IPluginService<T> service)
        {
            if ((service != null) && PluginService.Unregister(typeof(IPluginService<T>), service))
            {
                PluginLog.WriteAsync(string.Format(CultureInfo.InvariantCulture, "unregister service={0}", PluginTypeHelper.GetTypeName(service.GetType())));
            }
        }
    }
}

